<template>
  <el-container class="main-container">
    <!-- 侧边栏区域 -->
    <el-aside
      class="sidebar"
      :class="{ 'is-collapsed': isCollapsed }"
      :style="{ width: isCollapsed ? '80px' : '260px' }"
    >
      <div class="sidebar-header">
        <span v-if="!isCollapsed">对话历史</span>
        <el-button
        style="position: relative;left: 12px;"
          @click="toggleCollapse"
          :icon="isCollapsed ? 'el-icon-s-unfold' : 'el-icon-s-fold'"
          circle
        />
      </div>

      <el-menu
        :collapse="isCollapsed"
        :default-active="activeHistory"
        class="history-menu"
      >
        <el-menu-item
          v-for="chat in historyChats"
          :key="chat.id"
          :index="chat.id"
          @click="loadHistory(chat.id)"
        >
          <i class="el-icon-chat-line-round"></i>
          <span slot="title">{{ chat.title }}</span>
          <span class="history-time">{{ formatTime(chat.time) }}</span>
        </el-menu-item>
      </el-menu>
    </el-aside>

    <!-- 主内容区域 -->
    <el-main class="main-content">
      <el-card class="chat-box">
        <div ref="messages" class="message-area">
          <div v-for="(msg, index) in messages" :key="index">
            <div :class="['message', msg.role]">
              <div v-if="msg.type === 'text'">{{ msg.content }}</div>
              <div v-else-if="msg.type === 'file'" class="file-message">
                <i class="el-icon-document"></i>
                {{ msg.fileName }}
              </div>
            </div>
          </div>
        </div>

        <!-- 固定底部输入区域 -->
        <div class="input-container">
          <div class="input-area">
            <el-input
              v-model="inputMessage"
              placeholder="输入问题..."
              @keyup.enter.native="sendMessage"
            >
              <template #prepend>
                <el-button-group>
                  <el-tooltip content="语音输入">
                    <el-button
                      @click="toggleRecording"
                      :type="isRecording ? 'danger' : 'primary'"
                      icon="el-icon-microphone"
                    />
                  </el-tooltip>
                  <el-upload
                    action="/api/ai/upload"
                    :headers="uploadHeaders"
                    :on-success="handleUploadSuccess"
                    :on-error="handleUploadError"
                    :show-file-list="false"
                  >
                    <el-tooltip content="上传文件">
                      <el-button type="primary" icon="el-icon-upload" />
                    </el-tooltip>
                  </el-upload>
                </el-button-group>
              </template>

              <template #append>
                <div class="append-wrapper">
                  <el-dropdown trigger="click">
                    <el-button type="primary" icon="el-icon-more" />
                    <el-dropdown-menu slot="dropdown">
                      <el-dropdown-item @click.native="clearCurrentChat">
                        清除当前对话
                      </el-dropdown-item>
                      <el-dropdown-item @click.native="createNewChat">
                        新建对话
                      </el-dropdown-item>
                      <el-dropdown-item @click.native="showAllHistory">
                        全部历史
                      </el-dropdown-item>
                    </el-dropdown-menu>
                  </el-dropdown>
                  <el-button
                    type="primary"
                    icon="el-icon-position"
                    @click="sendMessage"
                    class="send-btn"
                  />
                </div>
              </template>
            </el-input>
          </div>
        </div>
      </el-card>
    </el-main>
  </el-container>
</template>

<script>
import axios from "@/utils/request";
import { getToken } from "@/utils/auth";

export default {
  data() {
    return {
      messages: [],
      inputMessage: "",
      isRecording: false,
      recognition: null,
      uploadHeaders: {
        Authorization: `Bearer ${getToken()}`,
      },
      isCollapsed: false,
      historyChats: [],
      activeHistory: null,
      currentChatId: null,
    };
  },
  mounted() {
    this.initSpeechRecognition();
    this.loadLocalHistory();
  },
  methods: {
    toggleCollapse() {
      this.isCollapsed = !this.isCollapsed;
    },

    initSpeechRecognition() {
      const SpeechRecognition =
        window.SpeechRecognition || window.webkitSpeechRecognition;
      if (SpeechRecognition) {
        this.recognition = new SpeechRecognition();
        this.recognition.lang = "zh-CN";
        this.recognition.interimResults = false;

        this.recognition.onresult = (event) => {
          const transcript = event.results[0][0].transcript;
          this.inputMessage += transcript;
        };

        this.recognition.onerror = (event) => {
          this.$message.error("语音识别错误: " + event.error);
        };
      }
    },

    toggleRecording() {
      if (!this.recognition) {
        this.$message.warning("浏览器不支持语音识别");
        return;
      }
      this.isRecording ? this.recognition.stop() : this.recognition.start();
      this.isRecording = !this.isRecording;
    },

    async sendMessage() {
      if (!this.inputMessage.trim()) return;

      if (!this.currentChatId) this.createNewChat();

      const userMessage = {
        role: "user",
        type: "text",
        content: this.inputMessage,
      };
      const aiMessage = { role: "ai", type: "text", content: "" };
      this.messages.push(userMessage, aiMessage);

      try {
        const response = await axios.post(
          "/api/ai/chat",
          { prompt: this.inputMessage },
          {
            headers: { Authorization: `Bearer ${getToken()}` },
            responseType: "json",
          }
        );

        const decoder = new TextDecoder();
        const reader = response.data.getReader();
        let buffer = "";

        while (true) {
          const { done, value } = await reader.read();
          if (done) break;

          buffer += decoder.decode(value);
          while (buffer.includes("\n")) {
            const line = buffer.substring(0, buffer.indexOf("\n"));
            buffer = buffer.substring(buffer.indexOf("\n") + 1);

            try {
              const data = JSON.parse(line);
              aiMessage.content += data.response;
              this.scrollToBottom();
            } catch (e) {
              console.error("JSON解析错误:", e);
            }
          }
        }
      } catch (error) {
        this.$message.error("请求失败: " + error.message);
      } finally {
        this.inputMessage = "";
        this.saveCurrentChat();
      }
    },

    loadHistory(chatId) {
      const targetChat = this.historyChats.find((c) => c.id === chatId);
      if (targetChat) {
        this.messages = [...targetChat.messages];
        this.activeHistory = chatId;
        this.currentChatId = chatId;
        this.scrollToBottom();
      }
    },

    createNewChat() {
      const newChat = {
        id: Date.now().toString(),
        title:
          this.inputMessage.trim() || `新对话 ${this.historyChats.length + 1}`,
        time: Date.now(),
        messages: [],
      };
      this.historyChats.unshift(newChat);
      this.currentChatId = newChat.id;
      this.messages = [];
      this.saveLocalHistory();
    },

    clearCurrentChat() {
      this.messages = [];
      this.saveCurrentChat();
    },

    saveCurrentChat() {
      const currentChat = this.historyChats.find(
        (c) => c.id === this.currentChatId
      );
      if (currentChat) {
        currentChat.messages = [...this.messages];
        currentChat.time = Date.now();
        this.saveLocalHistory();
      }
    },

    saveLocalHistory() {
      localStorage.setItem("chatHistory", JSON.stringify(this.historyChats));
    },

    loadLocalHistory() {
      const history = localStorage.getItem("chatHistory");
      if (history) {
        this.historyChats = JSON.parse(history);
        if (this.historyChats.length > 0) {
          this.currentChatId = this.historyChats[0].id;
          this.messages = [...this.historyChats[0].messages];
        }
      }
    },

    formatTime(timestamp) {
      const date = new Date(timestamp);
      return `${
        date.getMonth() + 1
      }/${date.getDate()} ${date.getHours()}:${date.getMinutes()}`;
    },

    handleUploadSuccess(response, file) {
      this.messages.push({
        role: "user",
        type: "file",
        fileName: file.name,
        content: response.fileUrl,
      });
      this.$message.success("文件上传成功");
      this.saveCurrentChat();
    },

    handleUploadError(err) {
      this.$message.error("文件上传失败: " + err.message);
    },

    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.messages;
        container.scrollTop = container.scrollHeight;
      });
    },
  },
};
</script>

<style scoped>
.main-container {
  height: 80%;
  overflow-x: hidden;
  left: -200px;
}

.sidebar {
  position: relative;
  left: -23px;
  height: 100vh;
  background: rgb(41, 109, 192);
  box-shadow: 2px 0 6px rgb(41, 109, 192);
  transition: all 0.3s;
}

.main-content {
  margin-left: -10px !important;
  transition: all 0.3s;
  width: calc(30%);
  height: 100vh;
  background: #f5f7fa;
}

.chat-box {
  height: 90%;
  display: flex;
  flex-direction: column;
}

.message-area {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  height: calc(90vh - 160px);
}

.input-container {
  height: 60px;
  border-radius: 10px;
  position: sticky;
  bottom: 0;
  background: #fff;
  z-index: 1000;
  padding: 10px;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
}

.message {
  margin: 10px 0;
  padding: 12px 16px;
  border-radius: 8px;
  max-width: 80%;
}

.message.user {
  background: #f5f7fa;
  margin-left: auto;
}

.message.ai {
  background: #e6f7ff;
  margin-right: auto;
}

@media screen and (max-width: 768px) {
  .sidebar {
    left: 0;
    transform: translateX(-100%);
  }

  .sidebar.active {
    transform: translateX(0);
  }

  .main-content {
    margin-left: 0 !important;
    width: 100%;
  }

  .message-area {
    height: calc(100vh - 140px);
  }
}
</style>
